package com.ggs.rg.ybjb.systemmodule.controller;

import com.alibaba.fastjson.JSONObject;
import com.ggs.rg.ybjb.pojomodule.pojo.TUser;
import com.ggs.rg.ybjb.pojomodule.util.CommonUtil;
import com.ggs.rg.ybjb.pojomodule.util.constants.ErrorEnum;
import com.ggs.rg.ybjb.systemmodule.config.SpringUtil;
import com.ggs.rg.ybjb.systemmodule.service.ConsumerService;
import com.ggs.rg.ybjb.systemmodule.service.UserService;
import com.ggs.rg.ybjb.systemmodule.util.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;

/**
 * ClassName:UserController
 * Package:com.ggs.rg.ybjb.usermodule.controller
 * Description:
 *             用户模块controller
 * @Date:2021/10/23 15:55
 * @Author:cxw
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private ConsumerService consumerService;

    private static RedisSessionDAO redisSessionDAO = SpringUtil.getBean(RedisSessionDAO.class);

    @GetMapping(value = "/login")
    public JSONObject login(HttpServletRequest request){
        //从前端中获取手机号和密码
        String loginFrom = request.getParameter("loginForm");
        JSONObject jsonParams = JSONObject.parseObject(loginFrom);

        //判断所需参数是否都有填写
        CommonUtil.hasAllRequired(jsonParams,"phone,password");
        String phone = jsonParams.getString("phone");
        String password = jsonParams.getString("password");
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //这个方法会调用ShiroSessionIdGenerator类中的获取sessionId的方法
        String sessionId = (String)subject.getSession().getId();
        System.out.println("请求获取到的sessionId的值为:" + sessionId);
        //封装用户登录信息
        UsernamePasswordToken token = new UsernamePasswordToken(phone,password);
        try{
            Collection<Session> sessions = redisSessionDAO.getActiveSessions();
            Object attribute = null;
            String sId = null ;
            for (Session sessionInfo : sessions) {
                //遍历Session,找到该用户名称对应的Session
                attribute = sessionInfo.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
                if (attribute == null) {
                    continue;
                }
                sId = (String)sessionInfo.getId();
                System.out.println("redis中获取到的sessionId的值为:" + sId);
                break;
            }
            //登录
            subject.login(token);
            if (attribute != null && !sId.equals(sessionId)){
                //登录验证成功后删除该用户原来的sessionId，单点登录
                ShiroUtils.deleteCache(phone,true);
            }
            TUser user = userService.getById(phone);
            if (user.getType())
                user.setLoginStatus(1);
            else
                user.setLoginStatus(2);
            return CommonUtil.successJson(user.getLoginStatus(),ShiroUtils.getSession().getId().toString());
        }catch (UnknownAccountException uae){ /*用户名不存在*/
            return CommonUtil.errorJson(ErrorEnum.E_10010,ShiroUtils.getSession().getId().toString());
        }catch (IncorrectCredentialsException ice) { /*密码错误*/
            return CommonUtil.errorJson(ErrorEnum.E_10010,ShiroUtils.getSession().getId().toString());
        }
//        catch (AuthenticationException ae) {
//            return CommonUtil.errorJson(ErrorEnum.E_10012,false);
//        }
    }

    @RequestMapping(value = "/register",method = RequestMethod.POST)
    public JSONObject register(@RequestBody JSONObject jsonObject){
        JSONObject registerForm = jsonObject.getJSONObject("registerForm");
        CommonUtil.hasAllRequired(registerForm,"phone,password,userName");
        String phone = registerForm.getString("phone");
        String password = registerForm.getString("password");
        Md5Hash md5Hash = new Md5Hash(password,phone);
        String userName = registerForm.getString("userName");
        //查询该用户是否已注册
        TUser dataUser = userService.getById(phone);
        if (dataUser != null)
            return CommonUtil.errorJson(ErrorEnum.E_10009,ShiroUtils.getSession().getId().toString());
        TUser tUser = new TUser(phone,md5Hash.toString(),userName,"默认头像.png");
        boolean save = userService.save(tUser);
        if (save){
            return CommonUtil.successJson(true,ShiroUtils.getSession().getId().toString());
        }else{
            return CommonUtil.errorJson(ErrorEnum.E_30001,ShiroUtils.getSession().getId().toString());
        }
    }

    @RequestMapping(value = "/logout",method = RequestMethod.GET)
    public JSONObject logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return CommonUtil.successJson(true,null);
    }

    @GetMapping(value = "/test")
    public ErrorEnum test(){
       return ErrorEnum.E_100;
    }


    //增加收货地址
    @PostMapping("/address/addAddress")
    public JSONObject addAddress(@RequestBody(required = false) JSONObject address){
        return CommonUtil.successJson(consumerService.addAddress(address),
                ShiroUtils.getSession().getId().toString());
    }

    //根据id删除收货地址
    @PostMapping("/address/deleteAddressByAid")
    public JSONObject deleteAddressByAid(@RequestBody(required = false) JSONObject params){
        return CommonUtil.successJson(consumerService.deleteAddressByAid(params),
                ShiroUtils.getSession().getId().toString());
    }

    //根据id更新收货地址
    @PostMapping("/address/updateAddressByAid")
    public JSONObject updateAddressByAid(@RequestBody(required = false) JSONObject address){
//        return CommonUtil.successJson(consumerService.updateAddressByAid(address),
//                ShiroUtils.getSession().getId().toString());
        return CommonUtil.errorJson(ErrorEnum.E_90003);
    }

    //查询用户所有收货地址
    @GetMapping("/address/getAddress")
    public JSONObject getAddress(@RequestParam(required = false) String phone){
        return CommonUtil.successJson(consumerService.getAddress(phone),
                ShiroUtils.getSession().getId().toString());
    }

    //首页分类展示商品
    @GetMapping("/goods/getGoodsByType")
    public JSONObject getGoodsByType(@RequestParam("type") String type,
                                     @RequestParam(value = "pagesNumber",required = false) Integer pagesNumber){
        return CommonUtil.successJson(consumerService.getGoodsByType(type,pagesNumber),
                ShiroUtils.getSession().getId().toString());
    }

    //首页搜索倒叙输出
    @GetMapping("/goods/searchGoodsByName")
    public JSONObject searchGoodsByName(@RequestParam("name") String name,
                                        @RequestParam(value = "pagesNumber",required = false) Integer pagesNumber){
        return CommonUtil.successJson(consumerService.searchGoodsByName(name,pagesNumber),
                ShiroUtils.getSession().getId().toString());
    }

    //把商品加入购物车
    @PostMapping("/shopping/addShopping")
    public JSONObject addShopping(@RequestBody JSONObject jsonObject){
        return CommonUtil.successJson(consumerService.addShopping(jsonObject),
                ShiroUtils.getSession().getId().toString());
    }

    //查询购物车 分页显示
    @GetMapping("/shopping/selectShopping")
    public JSONObject selectShopping(@RequestParam("phone") String phone,
                                     @RequestParam(value = "pagesNumber",required = false) Integer pagesNumber){
        return CommonUtil.successJson(consumerService.selectShopping(phone,pagesNumber),
                ShiroUtils.getSession().getId().toString());
    }

    //删除购物车
    @PostMapping("/shopping/deleteShopping")
    public JSONObject deleteShopping(@RequestBody JSONObject jsonObject){
        return CommonUtil.successJson(consumerService.deleteShopping(jsonObject),
                ShiroUtils.getSession().getId().toString());
    }

    //购物车生成订单
    @PostMapping("/shopping/addOrderByShopping")
    public JSONObject addOrderByShopping(@RequestBody JSONObject params){
        return CommonUtil.successJson(consumerService.addOrderByShopping(params),
                ShiroUtils.getSession().getId().toString());
    }

    //获取已付款订单,分页倒序
    @GetMapping("/order/getPaidOrdersByPhone")
    public JSONObject getPaidOrdersByPhone(@RequestParam(required = false) String phone,
                                           @RequestParam(required = false) Integer pagesNumber){
        return CommonUtil.successJson(consumerService.getPaidOrdersByPhone(phone,pagesNumber,1),
                ShiroUtils.getSession().getId().toString());
    }

    //获取未付款订单,分页倒序
    @GetMapping("/order/getUnPaidOrdersByPhone")
    public JSONObject getUnPaidOrdersByPhone(@RequestParam(required = false) String phone,
                                             @RequestParam(required = false) Integer pagesNumber){
        return CommonUtil.successJson(consumerService.getPaidOrdersByPhone(phone,pagesNumber,0),
                ShiroUtils.getSession().getId().toString());
    }

    //根据oid获取未付款订单详情
    @GetMapping("/order/getOrderDetailByOid")
    public JSONObject getOrderDetailByOid(@RequestParam String oid){
        return CommonUtil.successJson(consumerService.getOrderDetailByOid(oid),
                ShiroUtils.getSession().getId().toString());
    }

    //对订单进行付款
    @PostMapping("/order/payToMoney")
    public JSONObject payToMoney(@RequestParam String oid,@RequestParam Integer aid){
        return CommonUtil.successJson(consumerService.payToMoney(oid,aid),
                ShiroUtils.getSession().getId().toString());
    }

    //商品详情页生成订单(生成的订单都是未付款的)
    @PostMapping("/order/addOrder")
    public JSONObject addOrder(@RequestBody JSONObject params){
        return CommonUtil.successJson(consumerService.addOrder(params),
                ShiroUtils.getSession().getId().toString());
    }

    //取消订单,只能取消未付款的订单
    @PostMapping("/order/deleteOrdersByOid")
    public JSONObject deleteOrdersByOid(@RequestParam(required = false) String oid){
        return CommonUtil.successJson(consumerService.deleteOrdersByOid(oid),
                ShiroUtils.getSession().getId().toString());
    }

    //根据用户手机号查询指定用户
    @RequestMapping(value = "/userinfo/getUserInfoByPhone",method = RequestMethod.GET)
    public JSONObject getUserInfo(@RequestParam(value = "phone",required = false)String phone){
        return CommonUtil.successJson(consumerService.getUserInfo(phone),
                ShiroUtils.getSession().getId().toString());
    }

    //根据手机号更新用户信息
    @PostMapping(value = "/userinfo/updateUserInfo",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public JSONObject updateUserInfo(@RequestParam String phone,
                                     @RequestParam(required = false) String name,
                                     @RequestPart(required = false) MultipartFile image,
                                     @RequestParam(required = false) Boolean sex,
                                     @RequestParam(required = false) String desc,
                                     @RequestParam(required = false) String email,
                                     @RequestParam(required = false) Double money){
        return CommonUtil.successJson(consumerService.updateUserInfo(phone,name,image,sex,desc,email,money),
                ShiroUtils.getSession().getId().toString());
    }

    /*
    发布评论，
    用户只能在一个商品发布一个评论，管理员也只能回复一次。
     */
    @PostMapping("/comment/addUserComment")
    public JSONObject addUserComment(@RequestParam("text") String text,
                                     @RequestParam("pid") Integer pid,
                                     @RequestParam("phone") String phone,
                                     @RequestParam("oid") String oid,
                                     @RequestParam(value = "p1",required = false) MultipartFile p1){
        return CommonUtil.successJson(consumerService.addUserComment(text,pid,phone,oid,p1),
                ShiroUtils.getSession().getId().toString());
    }

}


